home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / permutation / permutation.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-18  |  5.3 KB  |  271 lines

  1. /* permutation/permutation.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <config.h>
  21. #include <gsl/gsl_errno.h>
  22. #include <gsl/gsl_permutation.h>
  23.  
  24. extern int gsl_check_range ; /* defined in vector/vector.c */
  25.  
  26. size_t
  27. gsl_permutation_size (const gsl_permutation * p)
  28. {
  29.   return p->size ;
  30. }
  31.  
  32. size_t *
  33. gsl_permutation_data (const gsl_permutation * p)
  34. {
  35.   return p->data ;
  36. }
  37.  
  38. #ifndef HIDE_INLINE_STATIC
  39. size_t
  40. gsl_permutation_get (const gsl_permutation * p, const size_t i)
  41. {
  42.   if (gsl_check_range)
  43.     {
  44.       if (i >= p->size)        /* size_t is unsigned, can't be negative */
  45.     {
  46.       GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0);
  47.     }
  48.     }
  49.  
  50.   return p->data[i];
  51. }
  52. #endif
  53.  
  54. int
  55. gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j)
  56. {
  57.   const size_t size = p->size ;
  58.   
  59.   if (i >= size)
  60.     {
  61.       GSL_ERROR("first index is out of range", GSL_EINVAL);
  62.     }
  63.  
  64.   if (j >= size)
  65.     {
  66.       GSL_ERROR("second index is out of range", GSL_EINVAL);
  67.     }
  68.  
  69.   if (i != j)
  70.     {
  71.       size_t tmp = p->data[i];
  72.       p->data[i] = p->data[j];
  73.       p->data[j] = tmp;
  74.     }
  75.   
  76.   return GSL_SUCCESS;
  77. }
  78.  
  79.  
  80. int
  81. gsl_permutation_valid (gsl_permutation * p)
  82. {
  83.   const size_t size = p->size ;
  84.  
  85.   size_t i, j ;
  86.  
  87.   for (i = 0; i < size; i++) 
  88.     {
  89.       if (p->data[i] >= size)
  90.         {
  91.           GSL_ERROR("permutation index outside range", GSL_FAILURE) ;
  92.         }
  93.  
  94.       for (j = 0; j < i; j++)
  95.         {
  96.           if (p->data[i] == p->data[j])
  97.             {
  98.               GSL_ERROR("duplicate permutation index", GSL_FAILURE) ;
  99.             }
  100.         }
  101.     }
  102.   
  103.   return GSL_SUCCESS;
  104. }
  105.  
  106. void
  107. gsl_permutation_reverse (gsl_permutation * p)
  108. {
  109.   const size_t size = p->size ;
  110.  
  111.   size_t i ;
  112.   
  113.   for (i = 0; i < (size / 2); i++) 
  114.     {
  115.       size_t j = size - i - 1;
  116.  
  117.       size_t tmp = p->data[i] ;
  118.       p->data[i] = p->data[j] ;
  119.       p->data[j] = tmp ;
  120.     }
  121. }
  122.  
  123. int 
  124. gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p)
  125. {
  126.   const size_t size = p->size ;
  127.  
  128.   size_t i ;
  129.  
  130.   if (inv->size != size)
  131.     {
  132.       GSL_ERROR("permutation lengths are not equal", GSL_EBADLEN);
  133.     }
  134.   
  135.   for (i = 0; i < size; i++) 
  136.     {
  137.       inv->data[p->data[i]] = i ;
  138.     }
  139.   
  140.   return GSL_SUCCESS ;
  141. }
  142.  
  143. int
  144. gsl_permutation_next (gsl_permutation * p)
  145. {
  146.   /* Replaces p with the next permutation (in the standard lexicographical
  147.    * ordering).  Returns GSL_FAILURE if there is no next permutation.
  148.    */
  149.   const size_t size = p->size;
  150.   size_t i, j, k;
  151.  
  152.   if (size < 2)
  153.     {
  154.       return GSL_FAILURE;
  155.     }
  156.  
  157.   i = size - 2;
  158.  
  159.   while ((p->data[i] > p->data[i+1]) && (i != 0))
  160.     {
  161.       i--;
  162.     }
  163.  
  164.   if ((i == 0) && (p->data[0] > p->data[1]))
  165.     {
  166.      return GSL_FAILURE;
  167.     }
  168.  
  169.   k = i + 1;
  170.  
  171.   for (j = i + 2; j < size; j++ )
  172.     {
  173.       if ((p->data[j] > p->data[i]) && (p->data[j] < p->data[k]))
  174.         {
  175.           k = j;
  176.         }
  177.     }
  178.  
  179.   /* swap i and k */
  180.  
  181.   {
  182.     size_t tmp = p->data[i];
  183.     p->data[i] = p->data[k];
  184.     p->data[k] = tmp;
  185.   }
  186.  
  187.   for (j = i + 1; j <= ((size + i) / 2); j++)
  188.     {
  189.       size_t tmp = p->data[j];
  190.       p->data[j] = p->data[size + i - j];
  191.       p->data[size + i - j] = tmp;
  192.     }
  193.  
  194.   return GSL_SUCCESS;
  195. }
  196.  
  197. int
  198. gsl_permutation_prev (gsl_permutation * p)
  199. {
  200.   const size_t size = p->size;
  201.   size_t i, j, k;
  202.  
  203.   if (size < 2)
  204.     {
  205.       return GSL_FAILURE;
  206.     }
  207.  
  208.   i = size - 2;
  209.  
  210.   while ((p->data[i] < p->data[i+1]) && (i != 0))
  211.     {
  212.       i--;
  213.     }
  214.  
  215.   if ((i == 0) && (p->data[0] < p->data[1]))
  216.     {
  217.       return GSL_FAILURE;
  218.     }
  219.  
  220.   k = i + 1;
  221.  
  222.   for (j = i + 2; j < size; j++ )
  223.     {
  224.       if ((p->data[j] < p->data[i]) && (p->data[j] > p->data[k]))
  225.         {
  226.           k = j;
  227.         }
  228.     }
  229.  
  230.   /* swap i and k */
  231.  
  232.   {
  233.     size_t tmp = p->data[i];
  234.     p->data[i] = p->data[k];
  235.     p->data[k] = tmp;
  236.   }
  237.  
  238.   for (j = i + 1; j <= ((size + i) / 2); j++)
  239.     {
  240.       size_t tmp = p->data[j];
  241.       p->data[j] = p->data[size + i - j];
  242.       p->data[size + i - j] = tmp;
  243.     }
  244.  
  245.   return GSL_SUCCESS;
  246. }
  247.  
  248. int
  249. gsl_permutation_memcpy (gsl_permutation * dest,
  250.                         const gsl_permutation * src)
  251. {
  252.   const size_t src_size = src->size;
  253.   const size_t dest_size = dest->size;
  254.  
  255.   if (src_size != dest_size)
  256.     {
  257.       GSL_ERROR ("permutation lengths are not equal", GSL_EBADLEN);
  258.     }
  259.  
  260.   {
  261.     size_t j;
  262.  
  263.     for (j = 0; j < src_size; j++)
  264.       {
  265.         dest->data[j] = src->data[j];
  266.       }
  267.   }
  268.  
  269.   return GSL_SUCCESS;
  270. }
  271.